/* eslint-disable no-case-declarations */
/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { defineComponent, ref, withModifiers, SetupContext } from 'vue';
import { ImageCropperProps, imageCropperProps } from './image-cropper.props';
import { useImageInfo } from './composition/use-image-info';

import './image-cropper.scss';

export default defineComponent({
    name: 'FImageCropper',
    props: imageCropperProps,
    emits: ['imageCropped', 'imageLoaded', 'cropperReady', 'loadImageFailed'] as (string[] & ThisType<void>) | undefined,
    setup(props: ImageCropperProps, context: SetupContext) {
        /** 图片居中 */
        const alignImage = ref(props.alignImage);
        /** 裁剪形状是否为圆形 */
        const roundCropper = ref(props.roundCropper);
        /** 隐藏重设大小的方块 */
        const hideResizeSquares = ref(props.hideResizeSquares);
        /** 图片加载错误的提示 */
        const loadImageErrorText = ref(props.loadImageErrorText);
        /** 是否禁用 */
        const disabled = ref(props.disabled);
        const wrapper = ref<HTMLDivElement | null>(null);

        const {uploadError,imageVisible,backgroundColor,sourceImage,safeImgDataUrl,
            safeTransformStyle,maxSize,cropper,marginLeft,moveTypes,isLoading,
            startMove,imageLoadedInView,moveStop,moveImg
        } = useImageInfo(props, context);

        function createResizeBar(direction: string) {
            return (
                <span
                    class={`farris-image-cropper-resize-bar ${direction}`}
                    onMousedown={withModifiers(
                        (payload: MouseEvent) => startMove(payload, moveTypes.Resize, direction),
                        ['prevent']
                    )}></span>
            );
        }
        function createCornerResizeBar(direction: string) {
            return (
                <div>
                    <span
                        class={`farris-image-cropper-resize-bar ${direction}`}
                        onMousedown={withModifiers((payload: MouseEvent) => startMove(payload, moveTypes.Resize, direction), ['prevent'])}>
                        <span class="farris-image-cropper-square"></span>
                    </span>
                    <span class="farris-image-cropper-resize top">
                        <span class="farris-image-cropper-square"></span>
                    </span>
                </div>
            );
        }
        const resizeBars = ['top', 'right', 'bottom', 'left'].map((direction) => createResizeBar(direction));
        const resizeCornerBars = ['topleft', 'topright', 'bottomright', 'bottomleft'].map((direction) => createCornerResizeBar(direction));

        return () => {
            return (
                <div
                    class={['farris-image-cropper-frame', { 'farris-image-cropper-disabled': disabled.value }]}
                    style={{ 'text-align': alignImage.value }}
                    onMousemove={withModifiers((payload: MouseEvent) => moveImg(payload), ['prevent'])}
                    onTouchmove={withModifiers((payload: TouchEvent) => moveImg(payload), ['prevent'])}
                    onMouseup={withModifiers(() => moveStop(), ['prevent'])}
                    onTouchend={withModifiers(() => moveStop(), ['prevent'])}>
                    {!uploadError && (
                        <div
                            ref={wrapper}
                            class="farris-image-cropper"
                            style={[{ background: imageVisible.value ? backgroundColor.value : '' }]}>
                            {safeImgDataUrl.value && (
                                <img
                                    ref={sourceImage}
                                    class="farris-source-image"
                                    style={[
                                        { visibility: imageVisible.value ? 'visible' : 'hidden' },
                                        { transform: safeTransformStyle.value }
                                    ]}
                                    src={safeImgDataUrl.value}
                                    onLoad={() => imageLoadedInView()}
                                />
                            )}
                            {maxSize.value && (
                                <div
                                    class="farris-image-overlay"
                                    style={[
                                        { width: `${maxSize.value.width || 0}px` },
                                        { height: `${maxSize.value.height || 0}px` },
                                        { 'margin-left': alignImage.value === 'center' ? marginLeft.value : '' }
                                    ]}></div>
                            )}
                            {imageVisible.value && (
                                <div
                                    class={['farris-image-cropper-wrapper', { 'farris-image-cropper-rounded': roundCropper.value }]}
                                    style={[
                                        { top: `${cropper.value.y1}px` },
                                        { left: `${cropper.value.x1}px` },
                                        { width: `${cropper.value.x2 - cropper.value.x1}px` },
                                        { height: `${cropper.value.y2 - cropper.value.y1}px` },
                                        { visibility: imageVisible.value ? 'visible' : 'hidden' },
                                        { 'margin-left': alignImage.value === 'center' ? marginLeft.value : '' }
                                    ]}
                                    tabindex="0">
                                    <div
                                        class="farris-image-cropper-move"
                                        onMousedown={withModifiers(
                                            (payload: MouseEvent) => startMove(payload, moveTypes.Move, 'topleft'),
                                            ['prevent']
                                        )}></div>
                                    {!hideResizeSquares.value && (
                                        <div>
                                            {resizeCornerBars}
                                            {resizeBars}
                                        </div>
                                    )}
                                </div>
                            )}
                        </div>
                    )}
                    {isLoading.value && (
                        <div class="farris-image-cropper-loading">
                            <div class="farris-image-cropper-loading-spinner"></div>
                        </div>
                    )}
                    {uploadError && <div class="farris-image-cropper-error">{loadImageErrorText.value}</div>}
                </div>
            );
        };
    }
});
